package com.sh;

import java.util.Objects;

public class ArrayList implements List {

    /**
     * transient 关键字修饰的属性不会被序列化
     */
    private transient Object[] elementData;
    private int size;   // 集合中元素个数  增加删除时要变化


    public ArrayList() {
        this(10);
    }

    public ArrayList(int initialCapacity) {
        elementData = new Object[initialCapacity];
    }

    @Override
    public int size() {
        return size;
    }

    @Override
    public Object get(int index) {
        if (index < 0 || index >= size) {
            throw new IndexOutOfBoundsException("索引越界异常" + index);
        }
        return elementData[index];
    }

    @Override
    public boolean isEmpty() {
        return size == 0;
    }

    @Override
    public boolean contains(Object o) {
        return indexOf(o) >= 0;   // 索引大于等于0就必定存在集合中
    }

    @Override
    public int indexOf(Object o) {
        int index = -1;
        if (o == null) {
            for (int i = 0; i < size; i++) {
                if (o.equals(elementData[i])) {
                    index = i;
                    break;
                }
            }
        } else {
            for (int i = 0; i < size; i++) {
                if (o.equals(elementData[i])) {
                    index = i;
                    break;
                }
            }
        }
        return index;
    }

    @Override
    public boolean remove(Object o) {
        final Object[] es = elementData;
        final int size = this.size;
        int i = 0;
        found:
        {
            if (o == null) {
                for (; i < size; i++)
                    if (es[i] == null)
                        break found;
            } else {
                for (; i < size; i++)
                    if (o.equals(es[i]))
                        break found;
            }
            System.out.println(o + " 元素不存在");
            return false;
        }

        final int newSize;
        if ((newSize = size - 1) > i)
            System.arraycopy(es, i + 1, es, i, newSize - i);
        es[this.size = newSize] = null;
        return true;
    }

    @Override
    public Object remove(int index) {
        Objects.checkIndex(index, size);
        final Object[] es = elementData;

        @SuppressWarnings("unchecked") Object oldValue = (Object) es[index];

        final int newSize;
        if ((newSize = size - 1) > index)
        /**
         * 将数组 es 中从索引 index + 1 开始的元素复制到数组 es 的索引 index 处，复制的元素个数为 newSize - index。
         */
            System.arraycopy(es, index + 1, es, index, newSize - index);
        es[this.size = newSize] = null;
        return oldValue;
    }


    @Override
    public void addAfter(Object obj, Object e) {

    }

    @Override
    public void add(int index, Object o) {
        if (elementData.length == size) {
            grow();
        }

        for (int i = size; i > index; i--) {
            elementData[i] = elementData[i - 1];
        }
        // 添加元素到指定位置
        elementData[index] = o;
        size++;
    }

    @Override
    public void add(Object o) {
        if (elementData.length == size) {
            grow();
        }
        // 添加元素到最后
        elementData[size] = o;
        size++;
    }

    // 扩容
    private void grow() {
        // 1. 创建一个新的数组
        // 1010  0101  0010   右移一位 == 整除2
        int oldCapacity = elementData.length;
        // int newCapacity = oldCapacity + oldCapacity >> 1;
        /**
         *  注意   位运算的优先级小于 +
         */
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        Object[] newArr = new Object[newCapacity];
        // 2. 原来数组中的元素拷贝到新数组中
        for (int i = 0; i < elementData.length; i++) {
            newArr[i] = elementData[i];
        }
        // 3. 引用指向新数组
        elementData = newArr;

        // 或者用一个工具类                      老数组            新数组长度
        // Object[] newArr = Arrays.copyOf(elementData, elementData.length * 2);
    }

    @Override
    public void addBefore(Object obj, Object e) {

    }


    @Override
    public Object replace(int i, Object e) {
        return null;
    }

    @Override
    public Iterator interator() {
        return new Itr();
    }

    private class Itr<T> implements Iterator<T> {
        int cursor = 0;

        @Override
        public boolean hasNext() {
            return cursor != size;
        }

        @Override
        public T next() {
            if (cursor >= size) {
                throw new RuntimeException("没有元素了");
            }
            return (T) elementData[cursor++];
        }
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder("[");
        for (int i = 0; i < size; i++) {
            builder.append(elementData[i] + " ,");
        }
        if (size > 0) {
            /**
             *  不大于0的话，说明数组中没有元素，builder里面没有逗号，直接toString()即可
             */
            builder.deleteCharAt(builder.length() - 1);
        }
        return builder.toString() + "]";
    }
}
